package com.han.hotelplat.quartz;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.aliyuncs.exceptions.ClientException;
import com.han.hotelplat.comm.Constant;
import com.han.hotelplat.comm.utils.DateUtil;
import com.han.hotelplat.comm.utils.LogUtil;
import com.han.hotelplat.comm.utils.MsgHelp;
import com.han.hotelplat.dao.task.TaskDao;
import com.han.hotelplat.manager.LogManager;
import com.han.hotelplat.model.TaskLogModel;
import com.han.hotelplat.pojo.childtask.Childtask;
import com.han.hotelplat.pojo.emtask.Emtask;
import com.han.hotelplat.pojo.hotelmanager.Hotelmanager;
import com.han.hotelplat.pojo.log.Logger;
import com.han.hotelplat.pojo.task.Task;
import com.han.hotelplat.service.bill.BillService;
import com.han.hotelplat.service.cashextract.CashExtractService;
import com.han.hotelplat.service.childtask.ChildTaskService;
import com.han.hotelplat.service.employee.EmployeeService;
import com.han.hotelplat.service.emtask.EmTaskService;
import com.han.hotelplat.service.hotelmanager.HotelmanagerService;
import com.han.hotelplat.service.task.TaskService;
import com.han.hotelplat.service.wallet.WalletService;

/**
 * 
	 ***************************************************************
	 * <p>
	 * @CLASS				:	TaskQuartz 任务相关定时器
	 * @DESCRIPTION	:	
	 * @AUTHOR				:	han1088
	 * @VERSION			:	v1.0
	 * @DATE					:	2018年3月12日 下午3:40:58            
	 * </p>
	 * 
	 * <p>
	 * @MODIFY	LOG	:		
	 * @AUTHOR				:	han1088
	 * @VERSION			:	v1.0
	 * @MODIFY DATE	:	
	 * </p>    
	 ****************************************************************
 */

/**
 * 业务相关的作业调度
 * 
           字段               允许值                           允许的特殊字符
	秒	 	0-59	 	, - * /
	分	 	0-59	 	, - * /
	小时	 	0-23	 	, - * /
	日期	 	1-31	 	, - * ? / L W C
	月份	 	1-12 或者 JAN-DEC	 	, - * /
	星期	 	1-7 或者 SUN-SAT	 	, - * ? / L C #
	年（可选）	 	留空, 1970-2099	 	, - * /
	
	*  字符代表所有可能的值
	/  字符用来指定数值的增量
	L  字符仅被用于天（月）和天（星期）两个子表达式，表示一个月的最后一天或者一个星期的最后一天
	6L 可以表示倒数第６天
	
 *
 */
@Component
public class TaskQuartz {
	@Autowired
	private TaskService taskService;
	@Autowired
	private TaskDao taskDao;
	@Autowired
	private EmTaskService emTaskService;
	@Autowired
	private ChildTaskService childTaskService;
	@Autowired
	private LogManager logManager;
	@Autowired
	private CashExtractService cashExtractService;
	@Autowired
	private WalletService walletService;
	@Autowired
	private BillService billService;
	@Autowired
	private HotelmanagerService hotelmanagerService;
	@Autowired
	private EmployeeService employeeService;
	
	
	public TaskQuartz() {
		this.printTimeStamp();  
        LogUtil.info("计划任务被初始化了");  
	} 
	public void printTimeStamp(){  
        Calendar ca= Calendar.getInstance();  
        ca.setTimeInMillis(System.currentTimeMillis());  
        SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS ", Locale.CHINA);  
        //显示当前时间 精确到毫秒  
        System.out.print(sdf.format(ca.getTime()));       
    }  
	/**
	 * 每天1点启动
	 * 0 30 1 * * ? 
	 */
	@Scheduled(cron = "0 30 01 * * ?")  
	public void scanTask(){
		//查询所有在服务中的任务修改为已服务状态
		List<Task> allInserviceLi = taskService.getHotelTask(null, Constant.TASK_STATE_INSERVICE,
				null, null);
		for(Task t:allInserviceLi){
			//查询前一天的考勤
			Date day = DateUtil.getRelativeDay(new Date(), -1);
			List<Childtask>ctli = childTaskService.getTaskAttendance(t.getTaskid(), DateUtil.formatYMD(day));
			for(Childtask ct :ctli){
				//如果房量为0并且待确认则修改为已确认
				if(ct.getRoomcount() == 0 &&
						(ct.getResult().intValue() == 1 || ct.getResult().intValue() == 2)){
						Childtask c = childTaskService.findChildTaskById(ct.getId());
						c.setResult(Constant.ATTENDANCE_HASAUTH);
						childTaskService.update(c);
				}
			}
		}
		
		//查询所有前一天到期的在服务中的任务修改为已服务状态
		List<Task> inserviceLi = taskService.getHotelTask(null, Constant.TASK_STATE_INSERVICE,
				null, DateUtil.getRelativeDay(new Date(), -1));
		for(Task t:inserviceLi){
			t.setState(Constant.TASK_STATE_HASSERVICE);//修改为已服务
			taskService.updateTask(t);
			LogUtil.info("任务【"+t.getTaskid()
					+ "】已服务");
		}
		
		//查询已发布的任务
		//1如果已经报名满了则修改为待服务状态
		//2如果已经到了开始时间但是没人报名的修改为已取消
		List<Task> publicserviceLi = taskService.getHotelTask(null, Constant.TASK_STATE_CREAT,
				null,null);
		for(Task t:publicserviceLi){
			System.out.println(t.getTaskid());
			List<Emtask> li = emTaskService.getEmTaskByTakid(t.getTaskid());
			if(li.size() == t.getUsercount().intValue()){//已经报名满了
				t.setState(Constant.TASK_STATE_WAITSERVICE);//修改为待服务
				taskService.updateTask(t);
				LogUtil.info("任务【"+t.getTaskid()+"】报名人数已经满了修改为待服务状态");
			}else if(t.getStarttime().getTime() <= System.currentTimeMillis()
					&& li.size() == 0){//开始时间已经过了但没人报名
				t.setState(Constant.TASK_STATE_CANCER);//修改为已取消
				t.setStopdate(new Date());
				t.setCancercause("【超时取消】抱歉，您的任务未有帮工报名，超时自动取消。");
				t.setCanceruser("3=0");//系统取消
				taskService.updateTask(t);
				Logger logger = new Logger(new Date(), "", null,"系统");
				String context = "系统取消任务";
				TaskLogModel tlm = new TaskLogModel();
				tlm.setContext(context);
				tlm.setOptcode(Constant.logger.LOG_TASK_CANCE);
				tlm.setTaskid(t.getTaskid());
				logManager.creatTaskLog(tlm, logger);
				LogUtil.info("任务【"+t.getTaskid()+"】没人报名修改为已取消状态");
				Hotelmanager hm = hotelmanagerService.findByUserid(t.getPublisher());
				try {
					//发送短信通知酒店
					MsgHelp.sendTimeoutTask(hm.getTel(), hm.getRealname(), t.getTaskid());
				} catch (ClientException e) {
					e.printStackTrace();
				}
			}else if(DateUtil.isSamDay(t.getStarttime())
					&& li.size() >0){
				t.setState(Constant.TASK_STATE_INSERVICE);//有人报名修改为服务中
				taskService.updateTask(t);
				LogUtil.info("任务【"+t.getTaskid()+"】开始时间已经到了修改为服务中状态");
			}
		}
		
		//查询已待服务的任务
		//1待服务的订单还没到开始时间的并且报名人数还没满的修改为发布中
		//2如果任务已经到了并且有人报名了开始时间修改为服务中
		List<Task> waitserviceLi = taskService.getHotelTask(null, Constant.TASK_STATE_WAITSERVICE,
				null,null);
		for(Task t:waitserviceLi){
			List<Emtask> li = emTaskService.getEmTaskByTakid(t.getTaskid());
			//待服务的订单还没到开始时间的并且报名人数还没满的修改为发布中
			if(li.size() < t.getUsercount().intValue()
					&& DateUtil.daysDistance(new Date(), t.getStarttime())>=1){
				t.setState(Constant.TASK_STATE_WAITSERVICE);//修改为待服务
				taskService.updateTask(t);
				LogUtil.info("任务【"+t.getTaskid()+"】报名人数已经满了修改为待服务状态");
			}
			//如果任务已经到了并且有人报名了开始时间修改为服务中
			if(li.size() >0 
					&& DateUtil.daysDistance(new Date(), t.getStarttime()) == 0){
				t.setState(Constant.TASK_STATE_INSERVICE);//修改为服务中
				taskService.updateTask(t);
				LogUtil.info("任务【"+t.getTaskid()+"】开始时间已经到了修改为服务中状态");
			}
		}
	}
	
	/**
	 * 每天2点创建当天的子任务订单
	 * 0 0 2 * * ? 
	 */
	@Scheduled(cron = "00 30 02 * * ?")  
	public void creatChildTask(){
		//查询所有在服务中的任务
		List<Task> inserviceLi = taskDao.getHotelTask(null,Constant.TASK_STATE_INSERVICE,null,null, null);
		List<Childtask>cli = new ArrayList<Childtask>();
		
		for(Task t:inserviceLi){
			//查询改任务接单的帮工
			List<Emtask> emtli = emTaskService.getEmTaskByTakid(t.getTaskid());
			for(Emtask et:emtli){
				if(et.getCanceltime() != null){
					continue;//帮工已经取消的就不用创建了
				}
				if(et.getIsstop() != null && et.getIsstop().intValue() == 1){
					continue;//服务中帮工已经取消的就不用创建了
				}
				Childtask ct = childTaskService.getTaskAttendance(t.getTaskid(), DateUtil.formatYMD(new Date()), et.getEmid());
				if(ct != null){//已经创建过不需要创建了
					continue;
				}
				ct = new Childtask();
				ct.setCreattime(new Date());
				ct.setEmid(et.getEmid());
				ct.setRealname(et.getRealname());
				ct.setResult(Constant.ATTENDANCE_NO_SUBMIMT);
				ct.setReward(0f);//单价*最低房量（实际的按结算）初始定位0
				ct.setCostmoney(0f);//酒店花费
				ct.setRoomcount(0f);//初始设定0个房间
				ct.setTaskid(t.getTaskid());
				cli.add(ct);
				LogUtil.info("系统为帮工【"+et.getRealname()+"】创建任务【"+t.getTaskid()+"】的子任务");
			}
		}
		LogUtil.info("存入队列中的条目数"+cli.size());
		int size = 0;
		for(Childtask ct : cli){
			LogUtil.info("插入数据帮工子任务："+ct.getRealname());
			childTaskService.save(ct);
			size ++;
		}
		LogUtil.info("创建考勤实际写入数据库条目："+size);
	}
}
